library(readr)
library(dplyr)
library(ggplot2)
library(tidyverse)
library(forcats)
library(ggthemes)
library(scales)
library(lubridate)
library(viridis)
library(knitr) # Package wird für Funktion kable() geladen
library(DT) # Package wird für Funktion datatable() geladen
library(gt) # Package wird für Funktion gt() geladen
library(kableExtra) # Package wird für detailiertere kable() bzw. kbl() Tabellen benötigt.Abschlussprojekt
rstatsZH-K009:
Packages laden
Einleitung
Hierbei handelt es sich um einen Übungscode bzw. -Dokument um die sich die Basics von R und Quarto-Dokumenten anzueignen.
Es erfolgt hierzu eine Auseinandersetzung mit den Daten zur Bevölkerung in Winterthur, welche einen Einblick in die Entwicklung des Ausländeranteils liefern sollen.
Daten laden
Import der Rohdaten der Stadt Winterthur
data_staatenkleingruppe_bfs <- read_csv(here::here("data/raw/Quartiere_Jahr_KTZH_00002604_00005328.csv"),
#detailiertere Betrachtung folgt später, deshalb Anzeige der Details hier unterdrückt
show_col_types = FALSE)Import der Rohdaten des Kanton Zürichs
data_auslaenderanteil_kantonal <- read_delim('https://www.web.statistik.zh.ch/ogd/data/KANTON_ZUERICH_205.csv',
#detailiertere Betrachtung folgt später, deshalb Anzeige der Details hier unterdrückt
show_col_types = FALSE)tbd geo coordinates
# tbd
# data_geo_coordinates_ktzh <- read_csvDaten
Bei den Rohdatenhandelt es sich um CSV Dateien aus dem Datenkatalog des Kantons Zürich.
Quellen
Bevölkerung, nach Staatenkleingruppe und Quartier
https://www.zh.ch/de/politik-staat/statistik-daten/datenkatalog.html#/datasets/2604@stadt-winterthurAusländeranteil
https://openzh.github.io/starter-code-openZH/
https://www.zh.ch/de/politik-staat/statistik-daten/datenkatalog.html#/datasets/68@statistisches-amt-kanton-zuerichLink zum GIS Browser Datendownload
https://www.zh.ch/de/politik-staat/statistik-daten/datenkatalog.html#/datasets/278@opendata-giszh-ktzh/distributions/1 bzw. http://maps.zh.ch/?topic=BASISKARTEZH&showtab=ogddownload
Analyseziele
Im Rahmen der Analyse werden die Daten aufbereitet und in ein Tidy Data Format gebracht, erkundet und visualisiert.
Teil 1
Erkenntnisse zur Veränderung des Ausländeranteils der letzten 10 Jahren der Stadt Winterthur sowie der letzten 3 Jahre der Stadtkreise Winterthurs schaffen.Teil 2
Ausländeranteil vergleichen mit i) kantonalen Zahlen und ii) geografische Heatmap erstellen.Benötigte Daten: Jahr, Ausländeranteil, Gebiet (inkl. Koordinaten)
Daten Aufbereitung
Erster Teil der Analyse, Entwicklung des Ausländeranteils der vergangenen 10 Jahre.
Datenbetrachtung
Vorwort zur Problemstellung mit “Viewern” in Quarto Dokumenten
Die Funktion
view()kann nicht in ein Quarto Dokument eingebettet werden und muss deshalb bei Erstellung desselben ausgeschlossen werden.Lösung
#| eval: falseverhindert die Ausführung des Codes. Der Code wird nicht evaluiert und keine Ergebnisse werden generiert.
#| echo: falseunterdrückt die Anzeige des Quellcodes im finalen Dokument. Der Code wird ausgeführt, aber nicht im Output angezeigt.Mittels beider Optionen wird der Code weder ausgeführt noch angezeigt. Nützlich um Code temporär zu deaktivieren oder zu dokumentieren, ohne ihn auszuführen oder anzuzeigen.
Die viewer
gt()undkable()produzieren u.U. komplexe/grosse Tabellen, dies kann zu Rendering-Problemen bei der Gerneration von Quarto-Dokumenten führen.Nachfolgend würden mit
gt()undkable()grosse Tabellen dargestellt werden, welche aufgrund Memory Exhaustion einen Seitenrefresh triggern und dadurch die Generierung des Quarto Dokuments abbrechen.Lösung
Als alternativer “Viewer” wird mit
datatable()eine reduzierte und zugleich interaktive Tabelle erstellt.
Daten betrachten (mit Ausgabe in Quarto-Dokument)
Komplettes dataframe als interaktive Tabelle
datatable() kann um Argumente ergänzt werden, um dem Nutzer rudimentäre Sortierungen und Suchen zu ermöglichen. (Table 1)
datatable(data_staatenkleingruppe_bfs,
filter = 'top',
options = list(pageLength = 5,
search = list(regex = TRUE,
caseInsensitive = TRUE)))Reduziertes dataframe mit SearchBuilder Funktion
Zur besseren Übersicht und aufgrund Redundanz mit Klarnamen, werden Spalten mit BFS-Nummern entfernt.
Für die individuelle Selektion durch den Nutzer kann die Extenstion 'SearchBuilder' aktiviert werden. (Table 2)
data_staatenkleingruppe <- data_staatenkleingruppe_bfs %>%
select(-contains("bfs_nr"))
data_staatenkleingruppe %>% datatable(filter = "top",
extensions = 'SearchBuilder',
options = list(pageLength = 10,
dom = 'Qlfrtip',
searchBuilder = TRUE))Betrachtung der Datentypen und eindeutigen Werten
glimpse() um einen “flüchtigen” Blick auf die Daten zu erhalten
glimpse(data_staatenkleingruppe)Rows: 7,306
Columns: 8
$ jahr <dbl> 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023,…
$ gemeinde <chr> "Winterthur", "Winterthur", "Winterthur", "Wint…
$ stadtkreis <chr> "Stadt", "Stadt", "Stadt", "Stadt", "Stadt", "S…
$ quartier <chr> "Altstadt", "Altstadt", "Altstadt", "Altstadt",…
$ staatenkleingruppe <chr> "Afrika", "Amerika", "Asien", "Australien und O…
$ region <chr> "übrige Kontinente", "übrige Kontinente", "übri…
$ anzahl <dbl> NA, 22, 29, NA, 130, 47, NA, NA, NA, 22, 23, NA…
$ anzahl_ist_kleingruppe <lgl> TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, T…
names() um alle Spaltenüberschriften zu erhalten
names(data_staatenkleingruppe)[1] "jahr" "gemeinde" "stadtkreis"
[4] "quartier" "staatenkleingruppe" "region"
[7] "anzahl" "anzahl_ist_kleingruppe"
unique() um die eindeutigen Werte spezifischer Spalten zu erhalten
unique(data_staatenkleingruppe$region)[1] "übrige Kontinente" "Nord-, Mittel- und Westeuropa"
[3] "Südeuropa" "Südosteuropa"
[5] "Osteuropa" "unbekannt"
unique(data_staatenkleingruppe$staatenkleingruppe) [1] "Afrika" "Amerika"
[3] "Asien" "Australien und Ozeanien"
[5] "Deutschland" "Italien"
[7] "Kosovo" "Mazedonien"
[9] "Nordeuropa" "Österreich"
[11] "Osteuropa und Russland" "Portugal"
[13] "Schweiz" "Serbien"
[15] "Spanien" "Türkei"
[17] "übriges Mitteleuropa" "übriges Südosteuropa"
[19] "Westeuropa" "Bosnien u. Herzegowina"
[21] "unbekannt"
unique(data_staatenkleingruppe$stadtkreis)[1] "Stadt" "Veltheim" "Seen" "Töss"
[5] "Mattenbach" "Oberwinterthur" "Wülflingen" "unbekannt"
unique(data_staatenkleingruppe$quartier) [1] "Altstadt" "Blumenau" "Brühlberg" "Büelwiesen" "Dättnau"
[6] "Deutweg" "Eichliacker" "Eidberg" "Endliker" "Ganzenbühl"
[11] "Gotzenwil" "Grüze" "Guggenbühl" "Gutschick" "Hardau"
[16] "Härti" "Hegi" "Hegmatten" "Heiligberg" "Iberg"
[21] "Lind" "Lindenplatz" "Neuburg" "Neuwiesen" "Niederfeld"
[26] "Oberfeld" "Oberseen" "Reutlingen" "Ricketwil" "Rosenberg"
[31] "Rossberg" "Schlosstal" "Sennhof" "Sonnenberg" "Stadel"
[36] "Taggenberg" "Talacker" "Tössfeld" "Waldegg" "Waser"
[41] "Weinberg" "Zinzikon" "unbekannt"
Einwohner pro Jahr (Table 3)
data_staatenkleingruppe %>% group_by(jahr) %>%
summarize(summe_anzahl = sum(anzahl, na.rm = TRUE))# A tibble: 10 × 2
jahr summe_anzahl
<dbl> <dbl>
1 2014 106415
2 2015 108007
3 2016 109632
4 2017 110585
5 2018 111651
6 2019 113006
7 2020 113969
8 2021 114971
9 2022 118134
10 2023 119419
Daten transformieren
“Unbekannt” prüfen / ausschliessen
Aus den vorangehenden unique()-Abfragen (Betrachtung der Datentypen und eindeutigen Werten) ist ersichtlich, dass einige Gebiete und Gruppen “unbekannt”-Einträge aufweisen.
Ein genauerer Blick auf die Daten zeigt, dass dieser Anteil in absoluten Zahlen über die gesamte Dekade im zweistelligen Bereich bleibt. Dies macht maximal 0.022% der Gesamtbevölkerung aus, wobei Durchschnitt und Median bei unter 0.00376% (Durchschnitt) bzw. 0.00094% (Median) bleiben.
Nachfolgende Übersicht mit gt() zeigt die Top 3 der “unbekannt”-Einträge pro Jahr, sowie Jahres-Durchschnitt und n-Median. (Table 4)
data_staatenkleingruppe %>%
#Nur Einträge mit Werten in Spalte "anzahl"
filter(anzahl_ist_kleingruppe !="TRUE") %>%
#Einwohner pro Jahr
group_by(jahr) %>%
mutate(einwohner_total = sum((anzahl), na.rm = TRUE)) %>%
ungroup() %>%
#Nur Zeilen mit unbekannt-Einträgen
filter(stadtkreis == "unbekannt" |
quartier == "unbekannt" |
staatenkleingruppe == "unbekannt" |
region == "unbekannt") %>%
#print(n=nrow(.)) %>%
#Spalten reduziern
select(-gemeinde, -staatenkleingruppe, -region) %>%
#Gruppieren
group_by(jahr, stadtkreis, quartier, einwohner_total) %>%
summarise(anzahl_unbekannt = sum(anzahl),
.groups = 'drop') %>%
#print(n=nrow(.)) %>%
group_by(jahr) %>%
mutate(einwohner_unbekannt_pct_jahr = round((anzahl_unbekannt / einwohner_total * 100), 5),
einwohner_unbekannt_total_jahr = sum(anzahl_unbekannt, na.rm = TRUE),
average_jahr = round(mean(einwohner_unbekannt_pct_jahr),5),
median_jahr = round(median(einwohner_unbekannt_pct_jahr),5)) %>%
arrange(desc(einwohner_unbekannt_pct_jahr)) %>%
#print(n=nrow(.)) %>%
slice_head(n = 3) %>%
#arrange(desc(einwohner_unbekannt_pct)) %>%
gt() %>%
summary_rows(columns = c(anzahl_unbekannt,
einwohner_unbekannt_pct_jahr),
fns = list(Summe = "sum")) %>%
tab_style(style = cell_fill(color = "lightblue"),
locations = cells_body(columns = c("einwohner_unbekannt_pct_jahr",
"average_jahr",
"median_jahr"))) %>%
opt_interactive(use_sorting = TRUE,
use_filters = TRUE)Aufgrund der vernachlässigbare Grössenordnung werden Zeilen mit “unbekannt”-Werten in der weiteren Betrachtung ausgeschlossen. (Table 5)
data_staatenkleingruppe_cleaned <- data_staatenkleingruppe %>%
filter(stadtkreis != "unbekannt" &
quartier != "unbekannt" &
staatenkleingruppe != "unbekannt" &
region != "unbekannt")
datatable(data_staatenkleingruppe_cleaned,
filter = "top",
extensions = 'SearchBuilder',
options = list(pageLength = 12,
dom = 'Qlfrtip',
searchBuilder = TRUE))NA prüfen / ausschliessen
Mit “anzahl_ist_kleingruppe” besteht eine Filtermöglichkeit für den NA-Ausschluss in Spalte “anzahl” (Table 6)
## Übersicht
data_staatenkleingruppe_cleaned %>%
group_by(anzahl_ist_kleingruppe, jahr) %>%
summarise(anzahl_zeilen = n(),
summe_anzahl = sum(anzahl, na.rm = TRUE))`summarise()` has grouped output by 'anzahl_ist_kleingruppe'. You can override
using the `.groups` argument.
# A tibble: 20 × 4
# Groups: anzahl_ist_kleingruppe [2]
anzahl_ist_kleingruppe jahr anzahl_zeilen summe_anzahl
<lgl> <dbl> <int> <dbl>
1 FALSE 2014 375 106363
2 FALSE 2015 383 107965
3 FALSE 2016 390 109582
4 FALSE 2017 389 110527
5 FALSE 2018 394 111594
6 FALSE 2019 400 112946
7 FALSE 2020 401 113906
8 FALSE 2021 410 114908
9 FALSE 2022 443 118061
10 FALSE 2023 442 119331
11 TRUE 2014 321 0
12 TRUE 2015 317 0
13 TRUE 2016 312 0
14 TRUE 2017 317 0
15 TRUE 2018 313 0
16 TRUE 2019 308 0
17 TRUE 2020 308 0
18 TRUE 2021 304 0
19 TRUE 2022 278 0
20 TRUE 2023 281 0
Nach Auschluss der NA-Werte haben alle Zeilen einen Wert in Spalte “anzahl” (Table 7)
## Auschluss NA-Zeilen
data_staatenkleingruppe_false <- data_staatenkleingruppe_cleaned %>%
filter(anzahl_ist_kleingruppe == FALSE)
data_staatenkleingruppe_false %>%
select(jahr,
stadtkreis,
region,
anzahl,
anzahl_ist_kleingruppe) %>%
datatable()Alternative Varianten, falls Filter auf NA-Werten nicht bereits existiert, sind u.a.
Filter auf Spalte “Anzahl
filter(is.na(anzahl)) bzw. filter(!is.na(anzahl))Filter auf Datensätze mit NA in irgendeiner resp. keiner Spalte
filter(if_any(everything(), is.na))
oder
data_staatenkleingruppe[complete.cases(data_staatenkleingruppe), ]bzw.
data_staatenkleingruppe[!complete.cases(data_staatenkleingruppe), ]Alternativer Code vorhanden aber nicht ausgeführt/ausgegeben im Quarto Dokument.
Feld 'herkunft' hinzufügen und dataframe auf benötigte Felder reduzieren
“Schweiz” ist als Wert vorhanden, ergo können alle ungleichen Werte als “Ausland” betrachtet werden. Das Feld herkunft ist sozusagen ein boolescher Datentyp.
Es wird davon ausgegangen, dass kein Schweizer zur Staatenkleingruppe “unbekannt” gehört.
NA-Werte sind bereits bereinigt (siehe NA prüfen / ausschliessen).
data_staatenkleingruppe_reduced <- data_staatenkleingruppe_false %>%
mutate(herkunft = case_when(staatenkleingruppe != "Schweiz" ~ "Ausland",
TRUE ~ "Schweiz")) %>%
select(jahr, herkunft, stadtkreis, quartier, anzahl) %>%
group_by(jahr, herkunft, stadtkreis, quartier) %>%
summarise(anzahl = sum(anzahl),
.groups = "drop")WICHTIG:
.groupsArgument wird benötigt. Das Ergebnis nach Verwendung vongroup_by()undsummarise()bleibt sonst standardmäßig gruppiert und so ist die Anzeige via z.B.gt()suboptimal.Nachfolgend ist ein Code Chunk mit
kable()undgt()aufgrund des Reender Problems ausgeschlossen (siehe Vorwort zur Problemstellung mit “Viewern” in Quarto Dokumenten)
Betrachtung des transformierten dataframes Table 8)
datatable(data_staatenkleingruppe_reduced,
filter = "top",
extensions = 'SearchBuilder',
options = list(pageLength = 8,
dom = 'Qlfrtip',
searchBuilder = TRUE))Speichern des transformierten dataframes
write_csv(x = data_staatenkleingruppe_reduced,
here::here("data/processed/data_staatenkleingruppe_reduced.csv"))Ergebnisse
Statistische Kennzahlen und Übersichten
Ausländeranteile der Stadt Winterthur der letzten 10 Jahre (Table 9) inkl. der Veränderung der Ausländerquote in Prozentpunkten.
Erkenntnis:
Es besteht eine stetige Zunahme des Ausländeranteils.
Die Zunahme bewegt sich im Promillebereich.
## Einwohner pro Jahr inkl. Ausländeranteil
## STADT
overview_city <- data_staatenkleingruppe_reduced %>%
group_by(jahr) %>%
summarize(einwohner = sum(anzahl, na.rm = TRUE),
einwohner_ausland = sum(anzahl[herkunft == "Ausland"], na.rm = TRUE),
anteil_ausland = einwohner_ausland / einwohner * 100,
einwohner_schweiz = sum(anzahl[herkunft != "Ausland"], na.rm = TRUE),
anteil_schweiz = einwohner_schweiz / einwohner * 100,
## Alternative für ungroup()
.groups = "drop") %>%
mutate(avg_anteil_ausland = mean(anteil_ausland),
median_anteil_ausland = median(anteil_ausland),
delta_anteil_ausland_yoy = anteil_ausland - lag(anteil_ausland)) %>%
ungroup() %>%
arrange(jahr) %>%
select(jahr,
einwohner,
einwohner_schweiz,
anteil_schweiz,
einwohner_ausland,
anteil_ausland,
delta_anteil_ausland_yoy,
avg_anteil_ausland,
median_anteil_ausland)
gt(overview_city) %>%
fmt_number(columns = c(einwohner, einwohner_schweiz, einwohner_ausland),
decimals = 0,
use_seps = TRUE,
sep_mark = "'") %>%
fmt_number(columns = delta_anteil_ausland_yoy,
decimals = 3,
use_seps = TRUE,
sep_mark = "'",
force_sign = TRUE) %>%
fmt_percent(columns = c(anteil_schweiz,
anteil_ausland,
anteil_ausland,
avg_anteil_ausland,
median_anteil_ausland),
decimals = 2,
scale_values = FALSE)| jahr | einwohner | einwohner_schweiz | anteil_schweiz | einwohner_ausland | anteil_ausland | delta_anteil_ausland_yoy | avg_anteil_ausland | median_anteil_ausland |
|---|---|---|---|---|---|---|---|---|
| 2014 | 106'363 | 83'091 | 78.12% | 23'272 | 21.88% | NA | 23.09% | 22.80% |
| 2015 | 107'965 | 84'200 | 77.99% | 23'765 | 22.01% | +0.132 | 23.09% | 22.80% |
| 2016 | 109'582 | 85'060 | 77.62% | 24'522 | 22.38% | +0.366 | 23.09% | 22.80% |
| 2017 | 110'527 | 85'668 | 77.51% | 24'859 | 22.49% | +0.114 | 23.09% | 22.80% |
| 2018 | 111'594 | 86'293 | 77.33% | 25'301 | 22.67% | +0.181 | 23.09% | 22.80% |
| 2019 | 112'946 | 87'043 | 77.07% | 25'903 | 22.93% | +0.262 | 23.09% | 22.80% |
| 2020 | 113'906 | 87'492 | 76.81% | 26'414 | 23.19% | +0.255 | 23.09% | 22.80% |
| 2021 | 114'908 | 87'957 | 76.55% | 26'951 | 23.45% | +0.265 | 23.09% | 22.80% |
| 2022 | 118'061 | 88'846 | 75.25% | 29'215 | 24.75% | +1.291 | 23.09% | 22.80% |
| 2023 | 119'331 | 89'316 | 74.85% | 30'015 | 25.15% | +0.407 | 23.09% | 22.80% |
Ausländeranteil der Stadtkreise von Winterthur der letzten 3 Jahre (Table 10) inkl. der Veränderung deren Ausländerquote in Prozentpunkten.
Erkenntnis:
Die Zunahme des Ausländeranteils je Stadtkreis während der letzten 3 Jahre bewegte sich bis auf zwei Ausnahmen bei unter 1%.
Die Zunahme bewegt sich im Promillebereich.
jahr_filter <- c(2023, 2022, 2021)
## STADTKREIS
overview_stadtkreis <- data_staatenkleingruppe_reduced %>%
group_by(jahr, stadtkreis) %>%
summarize(einw_sk = sum(anzahl, na.rm = TRUE),
einw_sk_ausland = sum(anzahl[herkunft == "Ausland"], na.rm = TRUE),
anteil_sk_ausland = einw_sk_ausland / einw_sk * 100,
einw_sk_schweiz = sum(anzahl[herkunft != "Ausland"], na.rm = TRUE),
anteil_sk_schweiz = einw_sk_schweiz / einw_sk * 100,
## Alternative für ungroup()
#.groups = "drop"
) %>%
ungroup() %>%
# der Gesamtwert "einwohner" besteht im df "overview_city" und kann anstelle erneuter berechnung mittels join dazu genommen werden.
left_join(overview_city, by = "jahr") %>%
mutate(anteil_sk_ausland_gesamt = (einw_sk_ausland / einwohner) * 100) %>%
mutate(anteil_einw_sk = einw_sk / einwohner * 100) %>%
arrange(stadtkreis, jahr) %>%
mutate(delta_anteil_ausland_yoy = anteil_sk_ausland - lag(anteil_sk_ausland)) %>%
# Erneute Gruppierung um die Delta je Jahr UND Quartier zu erhalten, ansonsten würde die Berechnung vom letzen Wert ohne Berücksichtung des Quartiers erfolgen. --> Für 2014 resultiert nun logischerweise ein NA Wert da kein Vergleich zum Vorjahr besteht.
group_by(stadtkreis) %>%
arrange(stadtkreis, jahr) %>%
mutate(delta_anteil_sk_ausland = anteil_sk_ausland - lag(anteil_sk_ausland)) %>%
ungroup() %>%
select(jahr,
stadtkreis,
einwohner,
einw_sk,
anteil_einw_sk,
einw_sk_schweiz,
anteil_sk_schweiz,
einw_sk_ausland,
anteil_sk_ausland,
delta_anteil_sk_ausland,
anteil_sk_ausland_gesamt,
delta_anteil_ausland_yoy)`summarise()` has grouped output by 'jahr'. You can override using the
`.groups` argument.
overview_stadtkreis %>%
filter(jahr %in% jahr_filter) %>%
gt() %>%
#cols_hide(columns = c("einw_sk_schweiz")) %>%
opt_interactive(
use_sorting = TRUE,
use_filters = TRUE,
use_resizers = TRUE,
use_highlight = TRUE) %>%
fmt_percent(columns = where(is.numeric) & matches("anteil") & !matches("jahr"),
decimals = 1,
scale_values = FALSE) %>%
fmt_number(columns = delta_anteil_ausland_yoy,
decimals = 3,
use_seps = TRUE,
sep_mark = "'",
force_sign = TRUE) %>%
fmt_number(columns = where(is.numeric) & !matches("anteil") & !matches("jahr"),
decimals = 0,
use_seps = TRUE,
sep_mark = "'") %>%
tab_style(style = cell_fill(color = "lightblue"),
locations = cells_body(columns = c("jahr",
"stadtkreis",
"einw_sk",
"anteil_einw_sk"))) %>%
tab_style(style = cell_fill(color = "lightyellow"),
locations = cells_body(columns = c("einw_sk_schweiz",
"anteil_sk_schweiz"))) %>%
tab_style(style = cell_fill(color = "wheat"),
locations = cells_body(columns = c("einw_sk_ausland",
"anteil_sk_ausland",
"delta_anteil_sk_ausland",
"anteil_sk_ausland_gesamt")))Ausländeranteil der Quartiere von Winterthur der letzten 10 Jahre (Table 11) inkl. der Veränderung deren Ausländerquote in Prozentpunkten.
jahr_filter <- max(data_staatenkleingruppe$jahr)
## Quartier
overview_quartier <- data_staatenkleingruppe_reduced %>%
group_by(jahr, quartier) %>%
summarize(einw_quartier = sum(anzahl, na.rm = TRUE),
einw_quartier_ausland = sum(anzahl[herkunft == "Ausland"], na.rm = TRUE),
anteil_quartier_ausland = einw_quartier_ausland / einw_quartier * 100,
einw_quartier_schweiz = sum(anzahl[herkunft != "Ausland"], na.rm = TRUE),
anteil_quartier_schweiz = einw_quartier_schweiz / einw_quartier * 100,
## Alternative für ungroup()
#.groups = "drop"
) %>%
ungroup() %>%
# der Gesamtwert "einwohner" besteht im df "overview_city" und kann anstelle erneuter berechnung mittels join dazu genommen werden.
left_join(overview_city, by = "jahr") %>%
mutate(anteil_quartier_ausland_gesamt = (einw_quartier_ausland / einwohner) * 100) %>%
mutate(anteil_einw_quartier = einw_quartier / einwohner * 100) %>%
#Erneute Gruppierung um die Delta je Jahr UND Quartier zu erhalten, ansonsten würde die Berechnung vom letzen Wert ohne Berücksichtung des Quartiers erfolgen. --> Für 2014 resultiert nun logischerweise ein NA Wert da kein Vergleich zum Vorjahr besteht.
group_by(quartier) %>%
arrange(quartier, jahr) %>%
mutate(delta_anteil_quartier_ausland = anteil_quartier_ausland - lag(anteil_quartier_ausland)) %>%
ungroup() %>%
select(jahr,
quartier,
einw_quartier,
anteil_einw_quartier,
einw_quartier_schweiz,
anteil_quartier_schweiz,
einw_quartier_ausland,
anteil_quartier_ausland,
delta_anteil_quartier_ausland,
einwohner,
anteil_quartier_ausland_gesamt)`summarise()` has grouped output by 'jahr'. You can override using the
`.groups` argument.
overview_quartier %>%
filter(jahr %in% jahr_filter) %>%
gt() %>%
fmt_percent(columns = where(is.numeric) & matches("anteil") & !matches("jahr"),
decimals = 1,
scale_values = FALSE) %>%
fmt_number(columns = delta_anteil_quartier_ausland,
decimals = 3,
use_seps = TRUE,
sep_mark = "'",
force_sign = TRUE) %>%
fmt_number(columns = where(is.numeric) & !matches("anteil") & !matches("jahr"),
decimals = 0,
use_seps = TRUE,
sep_mark = "'") %>%
tab_style(style = cell_fill(color = "lightblue"),
locations = cells_body(columns = c("jahr",
"quartier",
"delta_anteil_quartier_ausland",
"anteil_quartier_ausland_gesamt")))| jahr | quartier | einw_quartier | anteil_einw_quartier | einw_quartier_schweiz | anteil_quartier_schweiz | einw_quartier_ausland | anteil_quartier_ausland | delta_anteil_quartier_ausland | einwohner | anteil_quartier_ausland_gesamt |
|---|---|---|---|---|---|---|---|---|---|---|
| 2023 | Altstadt | 2'030 | 1.7% | 1'685 | 83.0% | 345 | 17.0% | +0.727 | 119'331 | 0.3% |
| 2023 | Blumenau | 4'601 | 3.9% | 3'413 | 74.2% | 1'188 | 25.8% | +0.313 | 119'331 | 1.0% |
| 2023 | Brühlberg | 2'129 | 1.8% | 1'751 | 82.2% | 378 | 17.8% | −1.236 | 119'331 | 0.3% |
| 2023 | Büelwiesen | 3'276 | 2.7% | 2'231 | 68.1% | 1'045 | 31.9% | +1.428 | 119'331 | 0.9% |
| 2023 | Deutweg | 7'251 | 6.1% | 5'541 | 76.4% | 1'710 | 23.6% | +0.231 | 119'331 | 1.4% |
| 2023 | Dättnau | 3'787 | 3.2% | 2'775 | 73.3% | 1'012 | 26.7% | +1.009 | 119'331 | 0.8% |
| 2023 | Eichliacker | 4'333 | 3.6% | 2'772 | 64.0% | 1'561 | 36.0% | +1.324 | 119'331 | 1.3% |
| 2023 | Eidberg | 165 | 0.1% | 165 | 100.0% | 0 | 0.0% | 0.000 | 119'331 | 0.0% |
| 2023 | Endliker | 2'177 | 1.8% | 1'501 | 68.9% | 676 | 31.1% | −0.120 | 119'331 | 0.6% |
| 2023 | Ganzenbühl | 3'058 | 2.6% | 2'303 | 75.3% | 755 | 24.7% | −0.009 | 119'331 | 0.6% |
| 2023 | Gotzenwil | 633 | 0.5% | 633 | 100.0% | 0 | 0.0% | −3.490 | 119'331 | 0.0% |
| 2023 | Grüze | 3'569 | 3.0% | 2'525 | 70.7% | 1'044 | 29.3% | +0.656 | 119'331 | 0.9% |
| 2023 | Guggenbühl | 5'785 | 4.8% | 3'580 | 61.9% | 2'205 | 38.1% | −0.004 | 119'331 | 1.8% |
| 2023 | Gutschick | 3'171 | 2.7% | 1'869 | 58.9% | 1'302 | 41.1% | +1.911 | 119'331 | 1.1% |
| 2023 | Hardau | 308 | 0.3% | 308 | 100.0% | 0 | 0.0% | 0.000 | 119'331 | 0.0% |
| 2023 | Hegi | 3'518 | 2.9% | 2'862 | 81.4% | 656 | 18.6% | −0.711 | 119'331 | 0.5% |
| 2023 | Hegmatten | 2'490 | 2.1% | 1'867 | 75.0% | 623 | 25.0% | +0.106 | 119'331 | 0.5% |
| 2023 | Heiligberg | 3'863 | 3.2% | 3'266 | 84.5% | 597 | 15.5% | +0.285 | 119'331 | 0.5% |
| 2023 | Härti | 3'578 | 3.0% | 2'304 | 64.4% | 1'274 | 35.6% | +0.539 | 119'331 | 1.1% |
| 2023 | Iberg | 1'090 | 0.9% | 1'015 | 93.1% | 75 | 6.9% | +0.172 | 119'331 | 0.1% |
| 2023 | Lind | 5'949 | 5.0% | 4'723 | 79.4% | 1'226 | 20.6% | +0.166 | 119'331 | 1.0% |
| 2023 | Lindenplatz | 3'101 | 2.6% | 2'187 | 70.5% | 914 | 29.5% | +0.613 | 119'331 | 0.8% |
| 2023 | Neuburg | 158 | 0.1% | 158 | 100.0% | 0 | 0.0% | 0.000 | 119'331 | 0.0% |
| 2023 | Neuwiesen | 4'218 | 3.5% | 3'205 | 76.0% | 1'013 | 24.0% | +1.819 | 119'331 | 0.8% |
| 2023 | Niederfeld | 2'058 | 1.7% | 1'632 | 79.3% | 426 | 20.7% | −0.065 | 119'331 | 0.4% |
| 2023 | Oberfeld | 5'401 | 4.5% | 3'730 | 69.1% | 1'671 | 30.9% | −0.085 | 119'331 | 1.4% |
| 2023 | Oberseen | 2'635 | 2.2% | 2'395 | 90.9% | 240 | 9.1% | −0.021 | 119'331 | 0.2% |
| 2023 | Reutlingen | 351 | 0.3% | 351 | 100.0% | 0 | 0.0% | 0.000 | 119'331 | 0.0% |
| 2023 | Ricketwil | 78 | 0.1% | 78 | 100.0% | 0 | 0.0% | 0.000 | 119'331 | 0.0% |
| 2023 | Rosenberg | 5'631 | 4.7% | 4'629 | 82.2% | 1'002 | 17.8% | +0.076 | 119'331 | 0.8% |
| 2023 | Rossberg | 32 | 0.0% | 32 | 100.0% | 0 | 0.0% | 0.000 | 119'331 | 0.0% |
| 2023 | Schlosstal | 3'346 | 2.8% | 2'194 | 65.6% | 1'152 | 34.4% | +0.721 | 119'331 | 1.0% |
| 2023 | Sennhof | 1'707 | 1.4% | 1'206 | 70.7% | 501 | 29.3% | +0.795 | 119'331 | 0.4% |
| 2023 | Sonnenberg | 896 | 0.8% | 868 | 96.9% | 28 | 3.1% | +0.128 | 119'331 | 0.0% |
| 2023 | Stadel | 276 | 0.2% | 276 | 100.0% | 0 | 0.0% | 0.000 | 119'331 | 0.0% |
| 2023 | Taggenberg | 1'026 | 0.9% | 915 | 89.2% | 111 | 10.8% | −0.380 | 119'331 | 0.1% |
| 2023 | Talacker | 6'601 | 5.5% | 4'915 | 74.5% | 1'686 | 25.5% | +0.986 | 119'331 | 1.4% |
| 2023 | Tössfeld | 4'499 | 3.8% | 3'349 | 74.4% | 1'150 | 25.6% | +0.056 | 119'331 | 1.0% |
| 2023 | Waldegg | 1'249 | 1.0% | 1'137 | 91.0% | 112 | 9.0% | +2.071 | 119'331 | 0.1% |
| 2023 | Waser | 5'577 | 4.7% | 4'115 | 73.8% | 1'462 | 26.2% | +0.520 | 119'331 | 1.2% |
| 2023 | Weinberg | 1'043 | 0.9% | 818 | 78.4% | 225 | 21.6% | +1.516 | 119'331 | 0.2% |
| 2023 | Zinzikon | 2'687 | 2.3% | 2'037 | 75.8% | 650 | 24.2% | −0.739 | 119'331 | 0.5% |
Visualisierung
Veränderung des Ausländeranteils der letzten 10 Jahren der
Stadt Winterthur (Figure 1)
# Entwicklung Ausländeranteil
ggplot(data = overview_city,
mapping = aes(x = factor(jahr),
y = anteil_ausland)) +
geom_col(position = "stack") +
geom_line(data = overview_stadtkreis,
aes(x = factor(jahr),
y = anteil_sk_ausland,
group = stadtkreis,
color = stadtkreis),
size = 1) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45,
hjust = 1)) +
scale_color_viridis_d() +
labs(x = "Jahr",
y = "Ausländeranteil (%)",
title = "Entwicklung Ausländeranteil Stadt Winterthur und deren Stadtkreise",
subtitle = "Balken: Gesamtstadt, Linien: Stadtkreise",
color = "Stadtkreis") +
scale_fill_viridis_d() +
scale_y_continuous(labels = scales::percent_format(scale = 1))Winterthur nach Stadtkreisen (Figure 2)
#Entwicklung Ausländeranteil nach Stadtkreis
ggplot(data = overview_stadtkreis,
mapping = aes(x = factor(jahr),
y = anteil_sk_ausland,
fill = stadtkreis)) +
geom_col(position = "stack") +
scale_fill_viridis_d() +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45,
hjust = 1)) +
labs(x = "Jahr",
y = "Ausländeranteil (%)",
title = "Entwicklung Ausländeranteil",
subtitle = "Gruppiert nach Stadtkreis") +
scale_y_continuous(labels = scales::percent_format(scale = 1)) +
facet_wrap(~ stadtkreis) +
labs(fill = "Stadtkreis")Stadtkreise Winterthur nach Jahr (Figure 3)
#Entwicklung Ausländeranteil nach Stadtkreis
ggplot(data = overview_stadtkreis,
mapping = aes(x = stadtkreis,
y = anteil_sk_ausland,
fill = factor(stadtkreis))) +
geom_col(position = "dodge") +
scale_fill_viridis_d() +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45,
hjust = 1)) +
labs(x = "Stadtkreis",
y = "Ausländeranteil (%)",
title = "Entwicklung Ausländeranteil",
subtitle = "Gruppiert nach Jahr") +
scale_y_continuous(labels = scales::percent_format(scale = 1)) +
facet_wrap(~ factor(jahr)) +
labs(fill = "Stadtkreis") Schlussfolgerung
In vier Gebieten liegt der Ausländeranteil über dem Durchschnitt der Stadt.
Figure 1Diese vier Gebiete sind Töss mit dem klar höchsten Wert, gefolgt von den Stadtkreisen Mattenbach, Oberwinterthur und Wülflingen.
Figure 3Über die letzten Jahre ist in allen Quartieren eine Zunahme zu verzeichnen.
Figure 2Die Zunahme bewegt sich im einstelligen Prozentbereich.
Table 9